/*
 * Sifteo SDK Example.
 */

#include <sifteo.h>
#include "assets.gen.h"
using namespace Sifteo;

static const unsigned gNumCubes = 3;
Random gRandom;


static AssetSlot MainSlot = AssetSlot::allocate()
    .bootstrap(GameAssets);

static Metadata M = Metadata()
    .title("Mandelbrot SDK Example")
    .package("com.sifteo.sdk.mandelbrot", "1.0")
    .icon(Icon)
    .cubeRange(gNumCubes);

RGB565 calculateMandelbrot(UInt2 pixel);
RGB565 calculateColorPalette(float shade);


class testRun{
public:

 void init(CubeID cube)
    {
        /*frame = 0;
        bg.x = 0;
        bg.y = 0;
*/
		
		 vid.initMode(BG0_SPR_BG1);
    //vid.colormap[0] = RGB565::fromRGB(0xFFFFFF);
	vid.attach(cube);
        passedTime = 0;


        // Our background is 18x18 to match BG0, and it seamlessly tiles
        vid.bg0.image(vec(0,0), Background);

        // Allocate 16x2 tiles on BG1 for text at the bottom of the screen
       vid.bg1.setMask(BG1Mask::filled(vec(0,14), vec(16,2)));
    }
void update(TimeDelta timeStep){
		passedTime += timeStep.seconds();
		if(passedTime > 3){
			writeText("test");
		}
		if(passedTime > 5){
			writeText("Haha bitches!");
		}
}

private:
 VideoBuffer vid;
 float passedTime;
     void writeText(const char *str)
    {
        // Text on BG1, in the 16x2 area we allocated
        vid.bg1.text(vec(0,14), Font, str);
    }

};

void main()
{

 static testRun instances[gNumCubes];


    for (unsigned i = 0; i < arraysize(instances); i++)
        instances[i].init(i);
    

    /*
     * Blank the screen. This also blanks the one-pixel region between
     * the bottom of the fractal and the top of the elapsed time indicator
     * below.
     */
	
	
	
TimeStep ts;
    // Kill time (efficiently)
     while (1) {
        for (unsigned i = 0; i < arraysize(instances); i++)
            instances[i].update(ts.delta());

        System::paint();
        ts.next();
    }
}

RGB565 calculateMandelbrot(UInt2 pixel)
{
    /*
     * Calculate one pixel of a Mandelbrot fractal,
     * using continuous shading based on a renormalizing technique.
     *
     * Reference: http://linas.org/art-gallery/escape/escape.html
     */

    const float radius2 = 400.f;
    const unsigned maxIters = 12;
    const float scale = 0.022f;
    const Int2 center = LCD_center + vec(25, 0);

    // We use Float2 vectors to store complex numbers
    Float2 z = vec(0, 0);
    Float2 c = (pixel - center) * scale;
    unsigned iters = 0;
    float modulus2;

    // Traditional Mandelbrot iteration
    do {
        z = z.cmul(z) + c;
        modulus2 = z.len2();
    } while (++iters <= maxIters && modulus2 <= radius2);

    // A couple extra iterations
    z = z.cmul(z) + c;
    z = z.cmul(z) + c;
    iters += 2;

    // Continuous shading, taking into account the iteration number as well
    // as how far outside the escape radius we are.
    float mu = (iters - log(log(z.len())) / M_LN2) / maxIters;

    if (mu < 1.0f) {
        // Exterior of fractal
        return calculateColorPalette(mu);
    } else {
        // Interior (didn't escape within our limit, or NaN)
        return RGB565::fromRGB(0x000000);
    }
}

RGB565 calculateColorPalette(float shade)
{
    // Specific colors that we'll interpolate between
    static const RGB565 stops[] = {
        RGB565::fromRGB(0x000000),
        RGB565::fromRGB(0x3216b0),
        RGB565::fromRGB(0xffa400),
        RGB565::fromRGB(0xfff800),
        RGB565::fromRGB(0xffffff),
    };

    // Convert normalized shade in [0,1] to a fractional stop index
    shade *= arraysize(stops) - 1;

    // What's the first color in the pair we're interpolating?
    int index = clamp<int>(shade, 0, arraysize(stops) - 2);

    // How far along are we from the first color to the second?
    int alpha = clamp<int>((shade - index) * 256.f, 0, 255);

    return stops[index].lerp(stops[index + 1], alpha);
}
